package com.xiaoyun.alllearning.controller;

import com.xiaoyun.alllearning.domain.common.PageQuery;
import com.xiaoyun.alllearning.domain.common.PageResult;
import com.xiaoyun.alllearning.domain.common.ResponseResult;
import com.xiaoyun.alllearning.domain.dto.UserDTO;
import com.xiaoyun.alllearning.domain.dto.UserQueryDTO;
import com.xiaoyun.alllearning.domain.vo.UserVo;
import com.xiaoyun.alllearning.exception.ErrorCodeEnum;
import com.xiaoyun.alllearning.service.ExcelExportService;
import com.xiaoyun.alllearning.service.UserService;
import com.xiaoyun.alllearning.util.InsertValidationGroup;
import com.xiaoyun.alllearning.util.UpdateValidationGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.objects.annotations.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/api/users")
@Slf4j
@Api
@Validated
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private ExcelExportService excelExportService;

    @CacheEvict(cacheNames = "users-cache", allEntries = true)
    @PostMapping
    @ApiOperation(value = "保存user")
    public ResponseResult save(@Validated(InsertValidationGroup.class) @RequestBody UserDTO userDTO) {
        int save = userService.save(userDTO);
        if (save == 1) {
            return ResponseResult.success("新增成功!");
        } else {
            return ResponseResult.failure(ErrorCodeEnum.INSERT_FAILURE);
        }

    }

    @ApiOperation("更新user")
    @PutMapping("/{id}")
    public ResponseResult update(@NotNull(message = "用户ID不能为空") @PathVariable Long id,
                                 @Validated(UpdateValidationGroup.class) @RequestBody UserDTO userDTO) {
        int update = userService.update(id, userDTO);
        if (update == 1) {
            return ResponseResult.success("更新成功！");
        } else {
            return ResponseResult.failure(ErrorCodeEnum.UPDATE_FAILURE);
        }

    }

    @ApiOperation("删除user")
    @DeleteMapping("/{id}")
    public ResponseResult delete(@NotNull(message = "用户ID不能为空") @PathVariable Long id) {
        int delete = userService.delete(id);
        if (delete == 1) {
            return ResponseResult.success("删除成功！");
        } else {
            return ResponseResult.failure(ErrorCodeEnum.DELETE_FAILURE);
        }

    }

    @ApiOperation("查询user")
    @Cacheable(cacheNames = "users-cache")
    @GetMapping
    public ResponseResult<PageResult> query(@NotNull Integer pageNo, @NotNull Integer pageSize,
                                            @Validated UserQueryDTO query) {
        log.info("未使用缓存~~");
        PageQuery<UserQueryDTO> pageQuery = new PageQuery<>();

        pageQuery.setPageNo(pageNo);
        pageQuery.setPageSize(pageSize);
        pageQuery.setQuery(query);

        PageResult<List<UserDTO>> pageResult = userService.query(pageQuery);

        List<UserVo> userVoList = Optional.ofNullable(pageResult.getData())
                .map(List::stream)
                .orElseGet(Stream::empty)
                .map(userDTO -> {
                    UserVo userVo = new UserVo();
                    BeanUtils.copyProperties(userDTO, userVo);
                    userVo.setPassword("******");
                    String phone = userDTO.getPhone();
                    if (!StringUtils.isEmpty(phone)) {
                        userVo.setPhone(userDTO.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
                    }
                    return userVo;
                }).collect(Collectors.toList());
        PageResult<List<UserVo>> result = new PageResult<>();
        BeanUtils.copyProperties(pageResult, result);
        result.setData(userVoList);
        return ResponseResult.success(result);

    }

    @GetMapping("/export")
    @ApiOperation("导出文件")
    @ApiImplicitParams(
            {@ApiImplicitParam(
                    value = "username", paramType = "query"
            ),
                    @ApiImplicitParam(
                            value = "filename", paramType = "query"
                    )}
    )
    public ResponseResult<Boolean> export(@Validated UserQueryDTO query, @NotEmpty String filename) {

        excelExportService.asyncExport(query, filename);

        return ResponseResult.success(Boolean.TRUE);
    }


}
